package com.pybox.service;

import com.pybox.common.utils.DateUtils;
import com.pybox.common.utils.JdbcTemplateUtils;
import com.pybox.common.utils.ParamUtils;
import com.pybox.dto.*;
import com.pybox.entity.TCabinets;
import com.pybox.entity.TObjects;
import com.pybox.entity.TObjectsCabinet;
import com.pybox.oauth.conf.UserDto;
import com.pybox.repository.*;
import com.pybox.util.CopyUtils;
import com.pybox.util.UserUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 描述：TObjects Service
 *
 * @author wuyingkai
 * @date 2018-09-15
 */

@Service
@Transactional
public class TObjectsService {

    @Autowired
    private TCabinetsRepository tCabinetsRepository;
    @Autowired
    private TObjectsRepository repository;
    @Autowired
    private TObjectsCabinetRepository tObjectsCabinetRepository;
    @Autowired
    private TObjectsCabinetService tObjectsCabinetService;
    @Autowired
    private TUserGroupObjectsRepository tUserGroupObjectsRepository;
    @Autowired
    private TCabinetsService tCabinetsService;
    @Autowired
    private JdbcTemplateUtils jdbcTemplateUtils;
    @Autowired
    private TModelsRepository modelsRepository;
    @Autowired
    private TObjectsRepository tObjectsRepository;

    /**
     * 创建TObjects
     *
     * @param source
     * @return
     */
    public boolean create(TObjectsDto source) {

        UserDto user = UserUtils.getCurrentUser();

        TObjects target = new TObjects();
        BeanUtils.copyProperties(source, target);
        target.setCtime(new Timestamp(DateUtils.getNowDate().getTime()));
        target.setDeleted(0);
        if (user.getCustomerId() != null && user.getCustomerId() > 0) {
            target.setCustomerId(user.getCustomerId());
        }
        repository.save(target);
        String objectIdUUId = target.getUuid();
        int objectId = target.getId();
        for (int i = 0; i < source.getTObjectsCabinetDto().size(); i++) {
            TObjectsCabinet TObjectsCabinet = new TObjectsCabinet();
            BeanUtils.copyProperties(source.getTObjectsCabinetDto().get(i), TObjectsCabinet);
            Integer cabinetId = source.getTObjectsCabinetDto().get(i).getCabinetId();
            TObjectsCabinet.setObjectId(objectId);
            TObjectsCabinet.setUkeyUuid(objectIdUUId);
            TObjectsCabinet.setCabinetUUId(tCabinetsRepository.findOne(cabinetId).getUuid());
            TObjectsCabinet.setCtime(new Timestamp(DateUtils.getNowDate().getTime()));
            TObjectsCabinet.setStatus(1);
            tObjectsCabinetRepository.save(TObjectsCabinet);
        }
        return true;

    }

    /**
     * 根据ID删除TObjects
     *
     * @param id
     * @return
     */
    public boolean delete(Integer id) {

        TObjects exist = repository.findOne(id);
        exist.setDeleted(1);
        repository.save(exist);
        return true;

    }

    /**
     * 更新TObjects
     *
     * @param id
     * @param source
     * @return
     */
    public boolean update(Integer id, TObjectsDto source) {

        TObjects exist = repository.findOne(id);
        if (null == exist) {
            throw new RuntimeException("记录不存在");
        }
        exist.setUtime(new Timestamp(DateUtils.getNowDate().getTime()));
        CopyUtils.copyProperties(source, exist);
        //修改过后将原来的关联关系全部更新，删除再新增
        tObjectsCabinetRepository.deleteByObjectId(source.getBoxId());
        for (TObjectsCabinetDto td : source.getTObjectsCabinetDto()) {
            TCabinets cabinets = tCabinetsRepository.findOne(td.getCabinetId());
            td.setObjectId(id);
            td.setStatus(0);
            td.setUkeyUuid(exist.getUuid());
            td.setCabinetUUId(cabinets.getUuid());
            tObjectsCabinetService.create(td);
        }
        exist.setDeleted(0);
        repository.save(exist);
        return true;

    }

    /**
     * 根据ID查询TObjects
     *
     * @param id
     * @return
     */
    public TObjectsDto detail(Integer id) {


        TObjects exist = repository.findOne(id);

        if (null == exist) {
            throw new RuntimeException("记录不存在");
        }

        TObjectsDto target = new TObjectsDto();
        BeanUtils.copyProperties(exist, target);

        TCabinetsDto tCabinetsDto;
        if (!"".equals(exist.getCabinetUid()) && exist.getCabinetUid() != null) {
            tCabinetsDto = tCabinetsService.getDetailByUUID(exist.getCabinetUid());
            if (!tCabinetsDto.equals(null))
                target.setCabinetName(tCabinetsDto.getName());
        }

        if (target.getModel() != 0) {
            target.setBrand(modelsRepository.findOne(target.getModel()).getModelName());

        } else {
            target.setBrand("新");
        }

        //gtarget增加 返回物品和柜子的信息
        List<TObjectsCabinetDto> list1 = new ArrayList<>();
        if (!StringUtils.isEmpty(target.getUuid())) {
            List<TObjectsCabinet> list = tObjectsCabinetRepository.findAllByUkeyUuid(target.getUuid());
            TCabinets cabinets;
            for (TObjectsCabinet tObjectsCabinet : list) {
                TObjectsCabinetDto tObjectsCabinetDto = new TObjectsCabinetDto();
                BeanUtils.copyProperties(tObjectsCabinet, tObjectsCabinetDto);
                cabinets = tCabinetsRepository.getTCabinetsByUuid(tObjectsCabinet.getCabinetUUId());
                if (cabinets != null) {
                    tObjectsCabinetDto.setName(cabinets.getName());
                    tObjectsCabinetDto.setCabinetId(cabinets.getId());
                }
                list1.add(tObjectsCabinetDto);
            }
        }

        if (target != null) {
            String position = target.getCabinetName() + ":" + target.getRow() + "行" + (target.getColumn()) + "列";
            target.setPosition(position);
        }
        target.setTObjectsCabinetDto(list1);
//        if (target.getModel() == 0) {
//            target.setBrand("新");
//           // target.setTmodels(modelsRepository.findAll());
//        }

        return target;

    }

    /**
     * 分页查询查询TObjects
     *
     * @param pageNo
     * @param pageSize
     * @param paramMap
     * @return
     */
    //@Cacheable(cacheNames="getAllObjectsCache",key="'getAllObjectsCache.page'")
    public Page<TObjectsDto> page(Integer pageNo, Integer pageSize, Map<String, String> paramMap) {
        Integer customerId = UserUtils.getCustomerId();
        paramMap.put("customerId", customerId.toString());

        //  Page<TObjects> data = repository.findAll(new TObjectsSpec(paramMap), pageable);
//
//        List<TObjectsDto> list = new ArrayList<>();
//        //未关联分组的物品id集合
        //List<Integer> objectIds = repository.getObjectsNoGroupId();
//        for (TObjects obj : data.getContent()) {
//            TCabinetsDto tCabinetsDto = new TCabinetsDto();
//            TObjectsDto dto = new TObjectsDto();
//            if ( obj.getCabinetUid() !=null && !"".equals(obj.getCabinetUid())){
//                tCabinetsDto = tCabinetsService.getDetailByUUID(obj.getCabinetUid());
//                if (tCabinetsDto == null) {
//                    dto.setCabinetName("");
//                } else {
//                    dto.setCabinetName(tCabinetsDto.getName());
//                }
//            }
//            BeanUtils.copyProperties(obj, dto);
//            if (objectIds.contains(dto.getId())){
//               dto.setIsRelated(0);
//            }else{
//                dto.setIsRelated(1);
//            }
//            list.add(dto);
//        }

        if (UserUtils.getIsAdmin() == 2) {

            return this.searchObjectByUserId(pageNo, pageSize, paramMap);

        } else {
            List<Object> object = new ArrayList<>();
            StringBuffer sql = new StringBuffer("SELECT\n" +
                    "\to.id,\n" +
                    "\to.`name`,\n" +
                    "\to.`status`,\n" +
                    "\to.uuid,\n" +
                    "\to.cabinet_uid,\n" +
                    "\to.token_pwd,\n" +
                    "\to.comments,\n" +
                    "\to.pos,\n" +
                    "\to.`row`,\n" +
                    "\to.col AS `column`,\n" +
                    "\to.color,\n" +
                    "\to.ctime,\n" +
                    "\to.model_id as model,\n" +
                    "\to.vincode6 AS vincode6,\n" +
                    "\to.utime,\n" +
                    "\tc.NAME AS cabinetName ,\n" +
                    "\tm.model AS brand\n" +
                    "FROM\n" +
                    "\tt_objects o\n" +
                    "\tLEFT JOIN t_cabinets c ON ( o.cabinet_uid = c.uuid ) \n" +
                    "\tLEFT JOIN t_models m ON (o.model_id = m.id) \n" +
                    "WHERE  1=1 \n");
            StringBuffer sb = new ParamUtils().getObjectsParams(paramMap, sql);
            Page<TObjectsDto> datas = jdbcTemplateUtils.page(sb, object, TObjectsDto.class, pageNo, pageSize);
            //未关联分组的物品id集合
            List<Integer> objectIds = repository.getObjectsNoGroupId();
            List<TObjectsDto> list = datas.getContent();

            for (TObjectsDto t : list) {
                if (t.getStatus() == 0)
                    t.setStatus(2);
                if (objectIds.contains(t.getId())) {
                    t.setIsRelated(0);
                } else {
                    t.setIsRelated(1);
                }
            }

            Page<TObjectsDto> page = new PageImpl<>(list, new PageRequest(pageNo - 1, pageSize), datas.getTotalElements());

            return page;
        }
    }


    /**
     * 一个物品关联多个组
     *
     * @param dto
     * @return
     */
    public Result<Boolean> updateGroupsByObjectId(ObjectGroupsDto dto) {
        //先删除再插入记录
        tUserGroupObjectsRepository.deleteGroupIdsByObjectId(dto.getObjectId());
        for (Integer groupId : dto.getGroupIds()) {
            tUserGroupObjectsRepository.addGroupIdByUserId(dto.getObjectId(), groupId);
        }
        return Result.ok(true);
    }

    //一个物品关联多个用户
    public Result<Boolean> updateUsersByObjectId(ObjectUsersDto dto) {
        //更新关联为空
        tUserGroupObjectsRepository.deleteUserIdsByObjectId(dto.getObjectId());
        for (Integer userId : dto.getUserIds()) {
            tUserGroupObjectsRepository.addUserIdByObjectId(userId, dto.getObjectId());
        }
        return Result.ok(true);
    }

    //根据物品获取关联的用户
    public Result<ObjectUsersDto> getUserIdsByObjectId(Integer ObjectId) {
        List<Integer> userIds = tUserGroupObjectsRepository.getUserIdsByObjectId(ObjectId);
        ObjectUsersDto dto = new ObjectUsersDto();
        dto.setUserIds(userIds);
        dto.setObjectId(ObjectId);
        return Result.ok(dto);
    }

    //根据物品获取关联的分组
    public Result<ObjectGroupsDto> getGroupIdsByObjectId(Integer ObjectId) {
        List<Integer> groupIds = tUserGroupObjectsRepository.getGroupIdsByObjectId(ObjectId);
        ObjectGroupsDto dto = new ObjectGroupsDto();
        dto.setGroupIds(groupIds);
        dto.setObjectId(ObjectId);
        return Result.ok(dto);
    }

    public Result<GroupObjectsDto> getObjectsNoGroupId() {
        GroupObjectsDto dto = new GroupObjectsDto();
        List<Integer> objectIds = repository.getObjectsNoGroupId();
        dto.setObjectIds(objectIds);
        return Result.ok(dto);
    }

    public List<TObjectsDto> searchAll() {
        List<Object> object = new ArrayList<>();
        StringBuffer sql = new StringBuffer("SELECT\n" +
                "\to.id,\n" +
                "\to.`name`,\n" +
                "\to.`status`,\n" +
                "\to.uuid,\n" +
                "\to.cabinet_uid,\n" +
                "\to.token_pwd,\n" +
                "\to.comments,\n" +
                "\to.pos,\n" +
                "\to.`row`,\n" +
                "\to.col AS `column`,\n" +
                "\to.color,\n" +
                "\to.vincode6 AS vincode6,\n" +
                "\to.utime,\n" +
                "\tc.NAME AS cabinetName ,\n" +
                "\tm.model AS brand\n" +
                "FROM\n" +
                "\tt_objects o\n" +
                "\tLEFT JOIN t_cabinets c ON ( o.cabinet_uid = c.uuid ) \n" +
                "\tLEFT JOIN t_models m ON (o.model_id = m.id)\n" +
                "WHERE\n" +
                "\to.deleted = 0\n");
        sql.append("  and o.customer_id = '" + UserUtils.getCustomerId() + "'");
        List<TObjectsDto> datas = jdbcTemplateUtils.list(sql, object, TObjectsDto.class);
        return datas;
    }


    /**
     * 根据用户Id分页查询TObjects
     *
     * @param pageNo
     * @param pageSize
     * @param paramMap
     * @return
     */
    public Page<TObjectsDto> searchObjectByUserId(Integer pageNo, Integer pageSize, Map<String, String> paramMap) {

        //获取用户Id
        int userId = UserUtils.getUserId();
        List<Object> object = new ArrayList<>();
        StringBuffer sb = new StringBuffer("SELECT\n" +
                "\to.id,\n" +
                "\to.name,\n" +
                "\to.userid_autherized,\n" +
                "\to.status,\n" +
                "\tc.NAME cabinetName,\n" +
                "\to.ctime   \n" +
                "\tFROM t_objects o \n" +
                "\tLEFT JOIN t_cabinets c \n" +
                "\t ON ( o.cabinet_uid = c.uuid ) WHERE o.id IN\n" +
                "\t (SELECT\n" +
                "\tobject_id \n" +
                "FROM\n" +
                "\tt_user_group_objects \n" +
                "WHERE\n");
        if (!StringUtils.isEmpty(userId)) {

            sb.append("   group_id IN ( SELECT group_id FROM t_user_group_objects WHERE user_id = '" + userId + "'")
                    .append(") \n" +
                            "\tAND object_id IS NOT NULL)\n" +
                            "\t");

        }
        if (!StringUtils.isEmpty(paramMap.get("name"))) {
            sb.append(" AND o.name like '%" + paramMap.get("name").trim() + "%'");
        }
        if (!StringUtils.isEmpty(paramMap.get("cabinetName"))) {
            sb.append(" AND c.name = '" + paramMap.get("cabinetName") + "'");
        }
        Page<TObjectsDto> datas = jdbcTemplateUtils.page(sb, object, TObjectsDto.class, pageNo, pageSize);
        Page<TObjectsDto> page = new PageImpl<>(datas.getContent(), new PageRequest(pageNo - 1, pageSize), datas.getTotalElements());
        return page;

    }
}